<?php
/**
 * Es数据库组件
*/

namespace houze;
use houze\elasticsearch\tool\Client;
use houze\elasticsearch\tool\Request;
use houze\elasticsearch\tool\Response;

class Elasticsearch
{
    /**
     * 强制指定使用某个节点
    */
    private $node = null;
    /**
     * 重试多少个节点，默认使用配置文件
    */
    private $retry_max_num = null;

    /**
     * 初始化配置
    */
    public function __construct() {
        $this->node = null;
        $this->retry_max_num = \houze\Config::get('elasticsearch.retry_max_num');
        return $this;
    }
    /**
     * 强制指定使用某个节点
    */
    public function config($node) {
        $this->node = $node;
        return $this;
    }
    /**
     * 指定重试多少个节点
    */
    public function retry($num) {
        $this->retry_max_num = $num;
        return $this;
    }
    /**
     * 发送请求
    */
    public function exec($url, $verb, $json=[], $node=[], $debug=false) {
        // 超过重试次数
        if (count($node) == $this->retry_max_num) return false;
        if (is_array($json)) {
            if (empty($json)) {
                $body = new \StdClass;
            } else {
                $body = json_encode($json);
            }
        } else {
            $body = $json;
        }
        
        if ($debug == true) return $body;

        // 获得一个节点
        $node_info = \houze\elasticsearch\tool\Client::get_node($node);
        // 已无节点可用
        if ($node_info == false) return false;

        // 发送请求
        $ret = Request::handle($url, $verb, $body, $node_info);
        // 发送失败，递归重试
        if ($ret == false) {
            $node[] = $node_info->getHost();
            return $this->exec($url, $verb, $json, $node);
        }

        return Response::handle($ret);
    }

    /**
     * ORM构造器注入
    */
    public function __call($name, $arguments=[]) {
        return call_user_func_array([new \houze\elasticsearch\orm\Builder($this), $name], $arguments);
    }
}